<!DOCTYPE html>
<html lang="zh">

<head>
	<th:block th:include="include :: header('Websocket消息')" />
</head>

<body class="gray-bg">
	<div class="wrapper wrapper-content animated fadeInRight">
		<div class="row">
			<div class="col-sm-12 search-collapse" style="display: block;">
				<div class="select-list ibox-content" >
					<ul>
						<li>
							<button class="btn btn-default " type="button" id="connect_btn"><i
									class="fa fa-map-marker"></i>&nbsp;&nbsp;<span
									id="connect_text">连接websocket</span></button>
						</li>
					</ul>
				</div>
			</div>
			<div class="col-sm-12 select-table table-striped">
				<div class="select-list ibox-content">
					<div class="row">
						<div class="col-sm-4">
							<div class="panel panel-default">
								<div class="panel-heading">
									单点
								</div>
								<style>
									.file-manager .folder-list li {
										width: 100%;
									}

									.collapse .panel-body {
										max-height: 450px;
										overflow-y: auto;
									}
								</style>
								<div class="panel-body">
									<div class="row">
										<div class="col-sm-4">
											<div class="panel-group" id="accordion" role="tablist"
												aria-multiselectable="true">
												<div class="panel panel-default">
													<div class="panel-heading" role="tab" id="headingOne">
														<h4 class="panel-title">
															<a role="button" data-toggle="collapse"
																data-parent="#accordion" href="#sendFriendMsg"
																aria-expanded="true" aria-controls="collapseOne">
																一对一（单聊）
															</a>
														</h4>
													</div>
													<div id="sendFriendMsg" class="panel-collapse collapse in"
														role="tabpanel" aria-labelledby="headingOne">
														<div class="panel-body">
															<div class="file-manager">
																<ul class="folder-list m-b-md" style="padding: 0">
																	<li>
																		<a href="javascript:void(0);"> <i
																				class="fa fa-inbox "></i> 收件箱 <span
																				class="label label-warning pull-right">16</span>
																		</a>
																	</li>
																</ul>
															</div>
														</div>
													</div>
												</div>
												<div class="panel panel-default">
													<div class="panel-heading" role="tab" id="headingTwo">
														<h4 class="panel-title">
															<a class="collapsed" role="button" data-toggle="collapse"
																data-parent="#accordion" href="#sendGroupMsg"
																aria-expanded="false" aria-controls="collapseTwo">
																多对多群聊
															</a>
														</h4>
													</div>
													<div id="sendGroupMsg" mu="u2" class="panel-collapse collapse"
														role="tabpanel" aria-labelledby="headingTwo">
														<div class="panel-body">
															<div class="file-manager">
																<ul class="folder-list m-b-md" style="padding: 0">
																	<li>
																		<a href="javascript:void(0);"> <i
																				class="fa fa-inbox "></i> 收件箱 <span
																				class="label label-warning pull-right">16</span>
																		</a>
																	</li>
																</ul>
															</div>
														</div>
													</div>
												</div>
												<div class="panel panel-default">
													<div class="panel-heading" role="tab" id="headingThree">
														<h4 class="panel-title">
															<a class="collapsed" role="button" data-toggle="collapse"
																data-parent="#accordion" href="#sendTopicMsg"
																aria-expanded="false" aria-controls="collapseThree">
																发送公告（一对多）
															</a>
														</h4>
													</div>
													<div id="sendTopicMsg" class="panel-collapse collapse" mu="u3"
														role="tabpanel" aria-labelledby="headingThree">
														<div class="panel-body">
															<div class="file-manager">
																<h5>发送公告（一对多）</h5>
																<ul class="folder-list m-b-md" style="padding: 0">
																	<li>
																		<a href="javascript:void(0);"> <i
																				class="fa fa-inbox "></i> 收件箱 <span
																				class="label label-warning pull-right">16</span>
																		</a>
																	</li>
																</ul>
															</div>
														</div>
													</div>
												</div>
												<div class="panel panel-default">
													<div class="panel-heading" role="tab" id="headingFour">
														<h4 class="panel-title">
															<a class="collapsed" role="button" data-toggle="collapse"
																data-parent="#accordion" href="#sendMeMsg"
																aria-expanded="false" aria-controls="collapseFour">
																给自己（单聊）
															</a>
														</h4>
													</div>
													<div id="sendMeMsg" class="panel-collapse collapse" mu="u3"
														role="tabpanel" aria-labelledby="headingFour">
														<div class="panel-body" style="height: 450px;overflow-y:auto;">
															<div class="file-manager">
																<h5>给自己（单聊）</h5>
																<ul class="folder-list m-b-md" style="padding: 0">
																	<li>
																		<a href="javascript:void(0);"> <i
																				class="fa fa-inbox "></i> 收件箱 <span
																				class="label label-warning pull-right">16</span>
																		</a>
																	</li>
																</ul>
															</div>
														</div>
													</div>
												</div>
											</div>
										</div>
										<div class="col-sm-8">
											<div class="row">
												<div class="col-sm-12">
													<div class="chat-discussion" style="height:600px;">
														<div class="chat-message">
															<div class="message">
																<a class="message-author" href="#"> 颜文字君</a>
																<span class="message-date"> 2015-02-02 18:39:23 </span>
																<span class="message-content">
																	H+ 是个好框架
																</span>
															</div>
														</div>
														<div class="chat-message">

															<div class="message">
																<a class="message-author" href="#"> 林依晨Ariel </a>
																<span class="message-date"> 2015-02-02 11:12:36 </span>
																<span class="message-content">
																	jQuery表单验证插件 - 让表单验证变得更容易
																</span>
															</div>
														</div>
														<div class="chat-message">

															<div class="message">
																<a class="message-author" href="#"> 谨斯里 </a>
																<span class="message-date"> 2015-02-02 11:12:36 </span>
																<span class="message-content">
																	验证日期格式(类似30/30/2008的格式,不验证日期准确性只验证格式
																</span>
															</div>
														</div>
														<div class="chat-message">
															<div class="message">
																<a class="message-author" href="#"> 林依晨Ariel </a>
																<span class="message-date"> 2015-02-02 - 11:12:36
																</span>
																<span class="message-content">
																	还有约79842492229个Bug需要修复
																</span>
															</div>
														</div>
														<div class="chat-message">
															<div class="message">
																<a class="message-author" href="#"> 林依晨Ariel </a>
																<span class="message-date"> 2015-02-02 11:12:36 </span>
																<span class="message-content">
																	九部令人拍案叫绝的惊悚悬疑剧情佳作】如果你喜欢《迷雾》《致命ID》《电锯惊魂》《孤儿》《恐怖游轮》这些好片，那么接下来推荐的9部同类题材并同样出色的的电影，绝对不可错过哦~

																</span>
															</div>
														</div>
														<div class="chat-message">
															<div class="message">
																<a class="message-author" href="#"> 林依晨Ariel </a>
																<span class="message-date"> 2015-02-02 11:12:36 </span>
																<span class="message-content">
																	九部令人拍案叫绝的惊悚悬疑剧情佳作】如果你喜欢《迷雾》《致命ID》《电锯惊魂》《孤儿》《恐怖游轮》这些好片，那么接下来推荐的9部同类题材并同样出色的的电影，绝对不可错过哦~

																</span>
															</div>
														</div>
														<div class="chat-message">
															<div class="message">
																<a class="message-author" href="#"> 林依晨Ariel </a>
																<span class="message-date"> 2015-02-02 11:12:36 </span>
																<span class="message-content">
																	九部令人拍案叫绝的惊悚悬疑剧情佳作】如果你喜欢《迷雾》《致命ID》《电锯惊魂》《孤儿》《恐怖游轮》这些好片，那么接下来推荐的9部同类题材并同样出色的的电影，绝对不可错过哦~

																</span>
															</div>
														</div>
														<div class="chat-message">
															<div class="message">
																<a class="message-author" href="#"> 林依晨Ariel </a>
																<span class="message-date"> 2015-02-02 11:12:36 </span>
																<span class="message-content">
																	九部令人拍案叫绝的惊悚悬疑剧情佳作】如果你喜欢《迷雾》《致命ID》《电锯惊魂》《孤儿》《恐怖游轮》这些好片，那么接下来推荐的9部同类题材并同样出色的的电影，绝对不可错过哦~

																</span>
															</div>
														</div>
														<div class="chat-message">
															<div class="message">
																<a class="message-author" href="#"> 林依晨Ariel </a>
																<span class="message-date"> 2015-02-02 11:12:36 </span>
																<span class="message-content">
																	九部令人拍案叫绝的惊悚悬疑剧情佳作】如果你喜欢《迷雾》《致命ID》《电锯惊魂》《孤儿》《恐怖游轮》这些好片，那么接下来推荐的9部同类题材并同样出色的的电影，绝对不可错过哦~

																</span>
															</div>
														</div>
													</div>
												</div>
												<div class="col-sm-12" style="width: 100%;height: 50px;">
													<div class="input-group">
														<input class="form-control" type="text" id="msg_input"> <span
															class="input-group-btn"> <button class="btn btn-primary"
																onclick="sendMeMsg();" type="button" id="send_btn">发送
															</button> </span>
													</div>
												</div>
											</div>

										</div>
									</div>

								</div>

							</div>
						</div>
						<div class="col-sm-4">
							<div class="panel panel-primary">
								<div class="panel-heading">
									群聊
								</div>
								<div class="panel-body">
									<p>通过 .panel-heading 可以很简单地为面板加入一个标题容器。你也可以通过添加设置了 .panel-title 类的标签，添加一个预定义样式的标题。
										为了给链接设置合适的颜色，务必将链接放到带有
										.panel-title 类的标题标签内。</p>
								</div>
							</div>
						</div>
						<div class="col-sm-4">
							<div class="panel panel-success">
								<div class="panel-heading">
									测试
								</div>
								<div class="panel-body">
									<div class="input-group">
										<label class="col-sm-3 control-label">消息内容：</label>
										<div class="col-sm-8">
											<input class="form-control" type="text" id="test_msg"><span
												class="input-group-btn"> <button class="btn btn-primary"
													onclick="sendMeMsg();" type="button">发送给自己
												</button> </span>
										</div>
									</div>
									<div class="input-group">
										<label class="col-sm-3 control-label">选择用户：</label>
										<div class="col-sm-8">
											<input class="form-control" type="text" id="test_choseUser">
											<span class="input-group-btn"> <button class="btn btn-primary"
													onclick="sendFriendMsg();" type="button">发到给指定用户
												</button> </span>
										</div>
									</div>
									<div class="input-group">
										<label class="col-sm-3 control-label">选择组：</label>
										<div class="col-sm-8">
											<input class="form-control" type="text" id="test_choseGroup">
											<span class="input-group-btn"> <button class="btn btn-primary"
													onclick="sendGroupMsg();" type="button">发到组
												</button> </span>
										</div>
									</div>

									<div class="input-group">
										<label class="col-sm-3 control-label">选择广播区域：</label>
										<div class="col-sm-8">
											<input class="form-control" type="text" id="test_choseTopic">
											<span class="input-group-btn"> <button class="btn btn-primary"
													onclick="sendTopicMsg();" type="button">发送广播
												</button> </span>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>

	<th:block th:include="include :: footer" />
	<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
	<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
	<script th:inline="JavaScript">
		var prefix = ctx + "oly/websocket";
		var webSocketMsg = "/websocket";
		var websocketOpen = false;
		$("#connect_btn").click(function () {
			if (!websocketOpen) {
				$.operate.get(prefix + "/connect", function (data) {
					if (window.WebSocket) {
						websocketConfig({ "token": data.data.session_id }, data.data.groupIds, data.data.topicIds);
						$("#connect_text").html("关闭websocket");
					} else {
						alert("错误", "浏览器不支持websocket技术通讯.");
					}
				});
			}
			else {
				disconnect();
				$("#connect_text").html("连接websocket");
			}

		});

		$('.folder-list a').click(function (e) {
			var req = $(this).data('req');
			var reqId = $(this).data('id');
			$.operate.get(prefix + req + "/" + reqId, function (data) {

			});
		});


		$('#accordion').on('shown.bs.collapse', function (e) {
			console.log(e.target.attributes.mu.nodeValue);
		})

		// 定义全局变量 stomp socket
		var stompClient, socket;

		// websocket 配置
		function websocketConfig(headers, groupIds, topicIds) {
			console.log(groupIds);
			/*
			 * 1. 连接url为endpointChat的endpoint,对应后台WebSoccketConfig的配置
			 * 2. SockJS 所处理的URL 是 "http://" 或 "https://" 模式，而不是 "ws://" or  "wss://"
			 */
			socket = new SockJS(prefix + "/register/websocketJS");

			// 通过sock对象监听每个事件节点，非必须,这个必须放在stompClient的方法前面
			sockHandle();

			// 获取 STOMP 子协议的客户端对象
			stompClient = Stomp.over(socket);

			/*
			 * 1. 获取到stomp 子协议后，可以设置心跳连接时间，认证连接，主动断开连接
			 * 2，连接心跳有的版本的stomp.js 是默认开启的，这里我们不管版本，手工设置
			 * 3. 心跳是双向的，客户端开启心跳，必须要服务端支持心跳才行
			 * 4. heartbeat.outgoing 表示客户端给服务端发送心跳的间隔时间
			 * 5. 客户端接收服务端心跳的间隔时间，如果为0 表示客户端不接收服务端心跳
			 */
			stompClient.heartbeat.outgoing = 10000;
			stompClient.heartbeat.incoming = 0;

			/*
			 * 1. stompClient.connect(headers, connectCallback, errorCallback);
			 * 2. headers表示客户端的认证信息,多个参数 json格式存,这里简单用的httpsessionID，可以根据业务场景变更
			 *    这里存的信息，在服务端StompHeaderAccessor 对象调用方法可以取到
			 * 3. connectCallback 表示连接成功时（服务器响应 CONNECTED 帧）的回调方法；
			 *    errorCallback 表示连接失败时（服务器响应 ERROR 帧）的回调方法，非必须；
			 */

			stompClient.connect(headers, function (frame) {
				console.log('Connected: ' + frame);
				/*
				 * 1. 订阅服务，订阅地址为服务器Controller 中的地址
				 * 2. 如果订阅为公告，地址为Controller 中@SendTo 注解地址
				 * 3. 如果订阅为私信，地址为setUserDestinationPrefix 前缀+@SendToUser注解地址
				 *    或者setUserDestinationPrefix 前缀 + controller的convertAndSendToUser地址一致
				 * 4. 这里演示为公告信息，所有订阅了的用户都能接受
				 */
				stompClient.subscribe("/topic/everyTopic", function (message) {
					var msg = JSON.parse(message.body).msg;
					console.log("接收到公告信息：" + msg);
					alert("接收到公告信息：" + msg);
				});

				/*
			   * 1. 订阅服务，订阅地址为服务器Controller 中的地址
			   * 2. 如果订阅为公告，地址为Controller 中@SendTo 注解地址
			   * 3. 如果订阅为私信，地址为setUserDestinationPrefix 前缀+@SendToUser注解地址
			   *    或者setUserDestinationPrefix 前缀 + controller的convertAndSendToUser地址一致
			   * 4. 这里演示为公告信息，所有订阅了的用户都能接受
			   */
				$.each($.parseJSON(topicIds), function (i, val) {
					stompClient.subscribe("/topic/topicId/" + val, function (message) {
						var msg = JSON.parse(message.body).msg;
						console.log("接收到公告信息：" + msg);
						alert("接收到公告信息：" + msg);
					});

				});


				$.each($.parseJSON(groupIds), function (i, val) {
					stompClient.subscribe("/mass/toGroup/" + val, function (message) {
						var msg = message.body;
						console.log("接收到点对点群消息：" + msg);
						alert("接收到点对点群消息：" + msg);
					});
				});

				/*
				 * 1. 因为推送为私信，必须带上或者setUserDestinationPrefix前缀 /user
				 * 2. 演示自己发送给自己，做websocket向服务器请求资源而已，然后服务器你就把资源给我就行了，
				 *    别的用户就不用你广播推送了，简单点，就是我请求，你就推送给我
				 */
				stompClient.subscribe("/user/alone/toMe", function (message) {
					var msg = JSON.parse(message.body).msg;
					console.log("接收到私信信息SendToUser：" + msg);
					alert("接收到私信信息SendToUser：" + msg);
				});

				/*
				 * 1. 订阅点对点消息
				 * 2. 很多博文这里的路径会写成"/user/{accountId}/userTest/callBack”这种，是因为
				 *    @SendToUser发送的代理地址是 /userTest/callBack， 地址将会被转化为 /user/{username}/userTest/callBack
				 *    username，为用户的登录名，也是就是Principal或者本文中的WebSocketUserAuthentication对象getName获取的参数
				 *    如果在拦截器中配置了认证路径，可以不带参数，不过推荐用带参数的写法
				 */
				stompClient.subscribe("/user/alone/toFriend", function (message) {
					var msg = message.body;
					console.log("接收到点对点SendToUser：" + msg);
					alert("接收到点对点SendToUser：" + msg);
				});
			}, function (error) {
				console.log('STOMP: ' + error);
				//setTimeout(websocketConfig, 10000);
				console.log('STOMP: Reconnecting in 10 seconds');
			});

		}

		function sendTopicMsg() {
			var msg = $("#test_msg").val();
			var data = { "msg": msg };
			var topicId = $("#test_choseTopic").val();
			/**
			 *  1. 第一个参数 url 为服务器 controller中 @MessageMapping 中匹配的URL，字符串，必须参数；
			 *  2. headers 为发送信息的header，json格式，JavaScript 对象，
			 *     可选参数,可以携带消息头信息，也可以做事务，如果没有，传{}
			 *  3. body 为发送信息的 body，字符串，可选参数
			 *  4. accountId这个参数其实可以通过header传过去，不过因为是restful风格，所以就跟在url上
			 */
			stompClient.send(webSocketMsg + "/sendTopicMsg/" + topicId, {}, JSON.stringify(data));
		}

		function sendGroupMsg() {
			var msg = $("#test_msg").val();
			var data = { "msg": msg };
			var groupId = $("#test_choseGroup").val();
			/**
			 *  1. 第一个参数 url 为服务器 controller中 @MessageMapping 中匹配的URL，字符串，必须参数；
			 *  2. headers 为发送信息的header，json格式，JavaScript 对象，
			 *     可选参数,可以携带消息头信息，也可以做事务，如果没有，传{}
			 *  3. body 为发送信息的 body，字符串，可选参数
			 */
			stompClient.send(webSocketMsg + "/sendGroupMsg/" + groupId, {}, JSON.stringify(data));
		}
		function sendMeMsg() {
			var msg = $("#test_msg").val();
			var data = { "msg": msg };

			/**
			 *  1. 第一个参数 url 为服务器 controller中 @MessageMapping 中匹配的URL，字符串，必须参数；
			 *  2. headers 为发送信息的header，json格式，JavaScript 对象，
			 *     可选参数,可以携带消息头信息，也可以做事务，如果没有，传{}
			 *  3. body 为发送信息的 body，字符串，可选参数
			 */
			stompClient.send(webSocketMsg + "/sendMeMsg", {}, JSON.stringify(data));
		}

		function sendFriendMsg() {
			var msg = $("#test_msg").val();
			var data = { "msg": msg };
			var friendId = $("#test_choseUser").val();
			/**
			 *  1. 第一个参数 url 为服务器 controller中 @MessageMapping 中匹配的URL，字符串，必须参数；
			 *  2. headers 为发送信息的header，json格式，JavaScript 对象，
			 *     可选参数,可以携带消息头信息，也可以做事务，如果没有，传{}
			 *  3. body 为发送信息的 body，字符串，可选参数
			 */
			stompClient.send(webSocketMsg + "/sendFriendMsg/" + friendId, {}, JSON.stringify(data));
		}



		// 通过sock对象监听每个事件节点，非必须，这里开启了stomp的websocket 也不会生效了
		function sockHandle() {
			// 连接成功后的回调函数
			socket.onopen = function () {
				console.log("------连接成功------");
			};

			// 监听接受到服务器的消息
			socket.onmessage = function (event) {
				console.log('-------收到的消息: ' + event.data);
			};

			// 关闭连接的回调函数
			socket.onclose = function (event) {
				console.log('--------关闭连接: connection closed.------');
			};

			// 连接发生错误
			socket.onerror = function () {
				alert("连接错误", "网络超时或通讯地址错误.");
				disconnect();
			};
		}

		// 关闭websocket
		function disconnect() {
			if (socket != null) {
				socket.close();
				socket = null;
			}
		}

	</script>
</body>

</html>